package org.shoukaiseki.kakaroto.domain;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.shoukaiseki.common.domain.SksEntity;
import org.shoukaiseki.common.utils.ListUtils;
import org.shoukaiseki.common.utils.StringUtils;
import org.shoukaiseki.kakaroto.FilterParser;
import org.shoukaiseki.kakaroto.Interface.DictTypeEnumData;
import org.shoukaiseki.kakaroto.constants.SksConstants;
import org.shoukaiseki.kakaroto.utils.TokenUserUtils;
import org.shoukaiseki.supersaiyan.common.core.domain.SysUser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 **/
public class BaseSO extends SksEntity {

    //前端扩展信息传入,与查询无关
    private JSONObject extraDataMap;

    /** 删除标志（0代表存在 1代表删除）,默认查询未删除的 */
    private Integer delFlag=0;

    /**
     *聚合查询使用的列名,如果不允许为null,或者空
     */
    private List<String> aggregatedQueryColumnList;

    /**
     * 关联显示的属性,如果启用则进行关联属性查询
     */
    private List<String> relationshipPropList;


    /**
     *聚合查询 group by 使用的列名,如果不允许为null,或者空
     */
    private List<String> aggregatedGroupByColumnList;

    /**
     * <pre>
     *     精确查找主键列表,该值如果不为null时,将会使用主键精确查找,
     *     无视delFlag标识,用于关联查询
     * </pre>
     */
    private Long[] exactQueryUniqueIdList;

    /**
     * <pre>
     *     排序过滤方案
     *    1: 计划完成时间排序 最近的在前面
     *    2: 计划完成时间 最近的在后面
     *
     *    myBatis代码
     * {@code
    <sql id="orderByProductionOrderLineRef">
    <choose>
    <when test="virtualOrderByFilterList != null and virtualOrderByFilterList.length &gt; 0">
    <foreach item="temp" collection="virtualOrderByFilterList" open=" order by" separator="," close="">
    <choose>
    <when test="temp==1">
    ifnull(planned_end_time,FROM_UNIXTIME(2147483647)) asc
    </when>
    <when test="temp==2">
    planned_end_time desc
    </when>
    <otherwise>
    production_order_line_id
    </otherwise>

    </choose>
    </foreach>
    </when>
    <otherwise>
    order by production_order_line_id
    </otherwise>
    </choose>
    </sql>
    <include refid="orderByProductionOrderLineRef"/>
    }
     * </pre>
     */
    private Integer[] virtualOrderByFilterList;

    /**
     * <pre>
     * 显示虚拟字段内容筛选器,为0或null不显示
     * 低16位用于是否显示虚拟对象  0xffff
     * 高15位用于是否显示虚拟列表(子表信息) 0x7fff0000
     * </pre>
     */
    private Integer showVirtualBitFilter;


    /**
     * 没有登录提示方式,0:返回null,2:3276801错误,3:返回空list
     */
//   private Short noLoginTips=0;

    /**
     * 为true时,tokenUserId 如果为null 则将tokenUserId设置为 0<br>
     *
     */
    private Boolean filterMy=false;

    /**
     * {@code
     * 按位过滤,该位为1开启
     *    &1: 为空
     * }
     */
    private  Integer lookupBitFilter;



    /**
     * 搜索值列表
     <pre>
     {@code
     <if test="searchValueList != null and searchValueList.length &gt; 0">
     <foreach item="temp" collection="searchValueList">
     and (item_name like concat('%',#{temp},'%')
     or var01 like concat('%',#{temp},'%')
     )
     </foreach>
     </if>
     }
     </pre>
     */


    private String[] searchValueList;

    /**
     * 包含主键列表
     <pre>
     {@code
     <if test="includeUniqueIdList != null">
     <choose>
     <when test="includeUniqueIdList.length==0">
     and inventory_balance_id is null
     </when>
     <otherwise>
     andinventory_balance_id in
     <foreach item="temp" collection="includeUniqueIdList" open="(" separator="," close=")">
     #{temp}
     </foreach>
     </otherwise>

     </choose>
     </if>
     }
     </pre>
     *
     */
    private Long[] includeUniqueIdList;

    /**
     * 排除主键列表
     <pre>
     {@code
     <if test="includeUniqueIdList != null and includeUniqueIdList.length &gt; 0">
     and inventory_balance_id not in
     <foreach item="temp" collection="includeUniqueIdList" open="(" separator="," close=")">
     #{temp}
     </foreach>
     </if>
     }
     </pre>
     */
    private Long[] excludeUniqueIdList;

    /**
     * 通过TokenUserService接口getTokenUserId() 设置该值,用户未登录会是null值
     */
    private Long tokenUserId;


    private Long orgId;


    private Long siteId;


    /** 请求参数 */
    private Map<String, Object> params=new HashMap<>();

    //sks JPA 过滤方式
    private Map<String,Object> sksParams;

    public Long getTokenUserId() {
        return tokenUserId;
    }

    public void setTokenUserId(Long tokenUserId) {
        this.tokenUserId = tokenUserId;
    }

    private Integer pageNum;

    private Integer pageSize;


    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }


    /**
     * 是否有分页功能
     * @return
     */
    public boolean havePageHeper(){
        return pageSize!=null;
    }

    public Boolean getFilterMy() {
        return filterMy;
    }

    public void setFilterMy(Boolean filterMy) {
        this.filterMy = filterMy;
    }

    public Integer getLookupBitFilter() {
        return lookupBitFilter;
    }

    public void setLookupBitFilter(Integer lookupBitFilter) {
        this.lookupBitFilter = lookupBitFilter;
    }

    public String[] getSearchValueList() {
        return searchValueList;
    }

    public void setSearchValueList(String... searchValueList) {
        this.searchValueList = searchValueList;
    }

    public Long[] getIncludeUniqueIdList() {
        return includeUniqueIdList;
    }

    public void setIncludeUniqueIdList(Long... includeUniqueIdList) {
        this.includeUniqueIdList = includeUniqueIdList;
    }

    public Long[] getExcludeUniqueIdList() {
        return excludeUniqueIdList;
    }

    public void setExcludeUniqueIdList(Long... excludeUniqueIdList) {
        this.excludeUniqueIdList = excludeUniqueIdList;
    }

    public Map<String, Object> getParams() {
        return params;
    }

    public void setParams(Map<String, Object> params) {
        this.params = params;
    }

    /**
     * 查询前执行初始化方法,防止用户隐私泄露<br>
     *  例如,获取关注的某商家总数<br>
     *   则在该方法中判断filterMy,如果为false,那么该方法中pageSize设置为-1,只能获取条数,不能获取关注的用户
     */
    public void initialize(){
        if(this.pageNum==null){
            this.pageNum=1;
        }
        if(this.pageSize==null){
            this.pageSize=50;
        }

    }

    @JsonIgnore
    @JsonProperty
    @JSONField(serialize = false)
    public JSONObject getExtraDataMap() {
        if(extraDataMap==null){
            extraDataMap=new JSONObject();
        }
        return extraDataMap;
    }

    public void setExtraDataMap(JSONObject extraDataMap) {
        this.extraDataMap = extraDataMap;
    }

    public Integer getShowVirtualBitFilter() {
        return showVirtualBitFilter;
    }

    public void setShowVirtualBitFilter(Integer showVirtualBitFilter) {
        this.showVirtualBitFilter = showVirtualBitFilter;
    }

    public Integer[] getVirtualOrderByFilterList() {
        return virtualOrderByFilterList;
    }

    public Long[] getExactQueryUniqueIdList() {
        return exactQueryUniqueIdList;
    }

    public void setExactQueryUniqueIdList(Long... exactQueryUniqueIdList) {
        this.exactQueryUniqueIdList = exactQueryUniqueIdList;
    }

    public List<String> getAggregatedQueryColumnList() {
        return aggregatedQueryColumnList;
    }

    public void setAggregatedQueryColumnList(List<String> aggregatedQueryColumnList) {
        this.aggregatedQueryColumnList = aggregatedQueryColumnList;
    }

    public Integer getDelFlag() {
        return delFlag;
    }

    public void setDelFlag(Integer delFlag) {
        this.delFlag = delFlag;
    }

    public List<String> getAggregatedGroupByColumnList() {
        return aggregatedGroupByColumnList;
    }

    public void setAggregatedGroupByColumnList(List<String> aggregatedGroupByColumnList) {
        this.aggregatedGroupByColumnList = aggregatedGroupByColumnList;
    }

    public Map<String, Object> getSksParams() {
        if(sksParams ==null){
            sksParams =new HashMap<>();
        }
        return sksParams;
    }

    public <T> T setSksParams(Map<String, Object> sksParams) {
        this.sksParams = sksParams;
        return (T)this;
    }


    public Map<String, ? extends SksEntity> getRelationshipMap() {
        return super.getRelationshipMap();
    }

    //CustomQO 转的时候需要该属性的值
    public String getMybatisRestrictionName() {
        return super.getMybatisRestrictionName();
    }

    //数据库查询时,使用的别名,默认用 t1
    public static final String TABLE_ALIAS_NAME="t1";

    public String sksTableAliasName(){
        return  TABLE_ALIAS_NAME;
    }

    //查询时使用的实际表和字段名(主要用于关联查询)
    public Map<String,String> columnNameWhereName(){
        return Map.of();
    }

    @JsonIgnore
    @JsonProperty
    @JSONField(serialize = false)
    public String getSksParamsWhereSql(){
//        return new FilterParser(getSksParams(),"sksParams","t1").parser();
        FilterParser filterParser = new FilterParser(getSksParams(), sksTableAliasName());
        //sql的字段名不进行陀峰转换
        //默认进行驼峰转换
        filterParser.setColumnCamelCaseConvert(true);
        //查询时使用的实际表和字段名(主要用于关联查询)
        filterParser.setColumnNameWhereName(columnNameWhereName());
        return filterParser.parser();
    }

    //应用程序限制
    @JsonIgnore
    @JsonProperty
    @JSONField(serialize = false)
    public String getAppRestrictionsSql(){
        return "";
    }

    public void setField(String key,Object value){
        if (params == null)
        {
            params = new HashMap<String,Object>();
        }
        params.put(key,value);
    }

    public List<String> getRelationshipPropList() {
        if (relationshipPropList==null) {
            relationshipPropList=new ArrayList<>();
        }
        return relationshipPropList;
    }

    public void setRelationshipPropList(List<String> relationshipPropList) {
        this.relationshipPropList = relationshipPropList;
    }

    public void addRelationshipPropList(String... relationshipProps) {
        List<String> relationshipPropList = getRelationshipPropList();
        for (String relationshipProp : relationshipProps) {
            if(StringUtils.isNotEmpty(relationshipProp)){
                relationshipPropList.add(relationshipProp);
            }
        }
    }

    public void virtualOrderByFilterList(DictTypeEnumData... virtualOrderByFilterList) {
        this.virtualOrderByFilterList = ListUtils.newArrayList(virtualOrderByFilterList).stream().map(o->((DictTypeEnumData)o).getValueInteger()).toArray(Integer[]::new);
    }

    public void setVirtualOrderByFilterList(Integer... virtualOrderByFilterList) {
        this.virtualOrderByFilterList = virtualOrderByFilterList;
    }

    //忽略删除标识过滤
    public void ignoreDelFlagWhere(){
        this.delFlag= SksConstants.DEL_FLAG_WhERE_SHOW_ALL;
    }

    public Long getOrgId() {
        return orgId;
    }

    public void setOrgId(Long orgId) {
        this.orgId = orgId;
    }

    public Long getSiteId() {
        return siteId;
    }

    public void setSiteId(Long siteId) {
        this.siteId = siteId;
    }

    /**
     * 过滤用户默认组织和地点的数据
     */
    public void filterTokenUserDefSiteAndDefOrg(){
        SysUser user = TokenUserUtils.getUser();
        setSiteId(user.getDefSiteId());
        setOrgId(user.getDefOrgId());
    }

}
